<template>
  <div class="container">
    <h3>vue+openlayers: 显示箭头的线段，箭头居中</h3>
    <div id="vue-openlayers" ref="map" class="map-x"></div>
  </div>
</template>

<script>
import 'ol/ol.css';
import {Map,View} from 'ol'
import Tile from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import VectorLayer from 'ol/layer/Vector'; // 矢量图层
import VectorSource from 'ol/source/Vector'; // 矢量数据源
import { Style, Stroke, Icon } from 'ol/style';
import Feature from 'ol/Feature'; // 要素
import { Point, LineString, Polygon } from 'ol/geom'; // 点要素
export default {
  data() {
    return {
      map: null,
      fea: null, // 线要素
      source: new VectorSource({ wrapX: false }), // 矢量数据源
      markersData: [
        
					[112.44837595417002, 23.186590101623924, 1604627953],
					[112.26981796722073, 22.48475773547695, 1604714353],
					[113.96115972956521, 22.25412016222777, 1604800753],
					[113.44837595417002, 23.186590101623924, 1604887153],
      ]
    }
  },

  mounted() {
    this.initMap();
  },
  methods: {
    addLine() {
      let LineStringFeature = new Feature(
        new LineString(this.markersData) // 线要素
      )
      LineStringFeature.setStyle(new Style({
        stroke: new Stroke({ // 设置线的样式
          color: '#f00',
          width: 2
        })
      }))

      this.fea = LineStringFeature // 保存线要素
      this.source.addFeature(LineStringFeature) // 添加线要素到数据源
    },

    arrowStyle() { // 箭头样式
      let geometry = this.fea.getGeometry() // 获取线要素的几何信息
      let Styles = [] // 箭头样式
      geometry.forEachSegment((start, end) => {
        let dx = end[0] - start[0] // 线段的x轴差值
        let dy = end[1] - start[1] // 线段的y轴差值
        let rotation = Math.atan2(dy, dx) // 线段的弧度
        let kx = (end[0] + start[0]) / 2 // 线段的中心点x轴坐标
        let ky = (end[1] + start[1]) / 2 // 线段的中心点y轴坐标
        Styles.push(new Style({
          geometry: new Point([kx, ky]), // 箭头的位置
          image: new Icon({
            src: require('@/assets/icon/love.svg'), // 箭头图片
            color: '#f00', // 箭头颜色
            anchor: [0.75, 0.5], // 锚点
            rotateWithView: true, // 旋转
            rotation: -rotation // 弧度
          })
        }))
      })
      return Styles
    },

    addPoint() {
      let features = []
      let data = this.markersData
      for(var i=0; i< data.length; i++) {
        let feature = new Feature({
          geometry: new Point([data[i][0], data[i][1]]),
        })
        feature.setStyle(this.arrowStyle())
        features.push(feature)
      }
      this.source.addFeatures(features)
    },

    initMap() {
      let raster = new Tile({
        source: new XYZ({
          url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7'
        })
      });
      let vector = new VectorLayer({
        source: this.source
      })

      this.map = new Map({
        target: this.$refs.map,
        layers: [raster, vector],
        view: new View({
          center: [113.44837595417002, 22.186590101623924],
          zoom: 10,
          projection: 'EPSG:4326'
        })
      })
      this.addLine()
      this.addPoint()
    }
  }
}
</script>

<style lang="scss" scoped>
.container {
    width: 840px;
    height: 550px;
    margin: 50px auto;
    border: 1px solid #ccc;
    #vue-openlayers {
      width: 800px;
      height: 420px;
      margin: 0 auto;
      border: 1px solid #42b983;
      position: relative;
    }
  }
</style>
